<?php

declare(strict_types=1);

namespace app\controller\system\org;

use app\BaseController;
use app\model\Org;
use app\service\factory\ResponseFactory;
use app\service\org\OrganizationService;
use app\validate\org\OrganizationValidate;
use InvalidArgumentException;
use think\Response;
use Throwable;

class Organization extends BaseController
{
    public function index(OrganizationService $organizationService): Response
    {
        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = $this->request->only([
                'keyword',
                'org_type',
                'status',
                'region_id',
                'invited_by',
            ], 'get');

            if ($this->request->has('ids')) {
                $ids = $this->request->param('ids');
                if (is_string($ids)) {
                    $ids = array_filter(array_map('intval', explode(',', $ids)));
                }
                if (is_array($ids)) {
                    $filters['ids'] = $ids;
                }
            }

            $paginator = $organizationService->paginate($filters, $page, $pageSize);
            $list = array_map(
                static fn(Org $org) => $organizationService->format($org),
                $paginator->items()
            );

            return json(ResponseFactory::paginated(
                $list,
                (int) $paginator->total(),
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function read(int $id, OrganizationService $organizationService): Response
    {
        try {
            $org = $organizationService->findById($id);
            if (!$org) {
                return json(ResponseFactory::error('组织不存在', 404));
            }

            return json(ResponseFactory::success($organizationService->format($org)));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function save(OrganizationService $organizationService): Response
    {
        try {
            $payload = $this->request->post();

            $this->validate($payload, OrganizationValidate::class . '.create');

            $org = $organizationService->create($payload);

            return json(ResponseFactory::success($organizationService->format($org), '组织已创建'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function update(int $id, OrganizationService $organizationService): Response
    {
        try {
            $org = Org::find($id);
            if (!$org) {
                return json(ResponseFactory::error('组织不存在', 404));
            }

            $payload = $this->request->put();
            $payload['id'] = $id;

            $this->validate($payload, OrganizationValidate::class . '.update');

            $updated = $organizationService->update($org, $payload);

            return json(ResponseFactory::success($organizationService->format($updated), '组织已更新'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function delete(int $id, OrganizationService $organizationService): Response
    {
        try {
            $org = Org::find($id);
            if (!$org) {
                return json(ResponseFactory::error('组织不存在', 404));
            }

            if (!$organizationService->delete($org)) {
                return json(ResponseFactory::error('删除失败', 500));
            }

            return json(ResponseFactory::success(true, '组织已删除'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }
}
